<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="Keywords" content="邮箱,前端系统,架构,alzui-mini" />
<meta name="Description" content="邮箱前端系统架构描述" />
<meta name="Author" content="apollo,wmingjian@163.com,alz_wmingjian@hotmail.com,mingjian@staff.sina.com.cn" />
<meta name="Version" content="0.01" />
<meta name="Create" content="2008-12-26" />
<title>邮箱前端系统架构</title>
<style type="text/css" rel="stylesheet">
<!--
HTML,BODY {width:100%;/*height:100%;*/margin:0px;padding:0px;/*overflow:hidden;*/}
DIV.body {width:100%;/*height:100%;overflow:auto;overflow-y:scroll;*/background-color:#DDDDDD;/*text-align:center;*/}
.wui-doc {margin:20px auto 20px auto;width:600px;background-color:#F8F8F8;padding:10px/*;border:#CCCCCC 1px solid;*/}
.wui-doc TD,
.wui-doc TH,
.wui-doc A,
.wui-doc DIV,
.wui-doc PRE {font:12px "Tahoma","宋体","Courier New";line-height:120%;}
.wui-doc A,
.wui-doc A:visited {color:#000080;text-decoration:none;}
.wui-doc A:active  {color:#FF0000;text-decoration:none;}
.wui-doc A:hover   {color:#000080;text-decoration:underline;}
.wui-doc IMG {vertical-align:middle;}
.wui-doc IMG.wui-icon {border:0px;margin-right:2px;}
.wui-doc TABLE {font:12px "Tahoma","宋体","Courier New";border-collapse:collapse;}
.wui-doc SPAN {line-height:140%;}
.wui-doc OL,
.wui-doc UL {margin:4px 0px 4px 0px;padding-left:16px;font:12px "Tahoma","宋体","Courier New";text-align:left;background-color:#EFEFEF;/*margin-left:24px;*/}
.wui-doc LI {list-style:none;font:12px "Tahoma","宋体","Courier New";text-align:left;line-height:140%;}
.wui-doc DT,
.wui-doc DL {text-align:left;margin-top:2px;margin-bottom:2px;background-color:#EFEFEF;}
.wui-doc H1 {margin:20px 0px 9px 0px;text-indent:4px;font:bold 17px "Tahoma","宋体","Courier New";text-align:left;height:24px;line-height:24px;background-color:#EFEFEF;}
.wui-doc H2 {margin:16px 0px 8px 0px;text-indent:4px;font:bold 16px "Tahoma","宋体","Courier New";text-align:left;height:24px;line-height:24px;background-color:#EFEFEF;}
.wui-doc H3 {margin:12px 0px 7px 0px;text-indent:4px;font:bold 15px "Tahoma","宋体","Courier New";text-align:left;height:24px;line-height:24px;background-color:#EFEFEF;}
.wui-doc H4 {margin:8px 0px 6px 0px;text-indent:4px;font:bold 14px "Tahoma","宋体","Courier New";text-align:left;height:24px;line-height:24px;background-color:#EFEFEF;}
.wui-doc H5 {margin:6px 0px 5px 0px;text-indent:4px;font:bold 13px "Tahoma","宋体","Courier New";text-align:left;height:20px;line-height:20px;background-color:#EFEFEF;}
.wui-doc H6 {margin:4px 0px 4px 0px;text-indent:4px;font:bold 12px "Tahoma","宋体","Courier New";text-align:left;height:16px;line-height:16px;background-color:#EFEFEF;}
.wui-doc P.title {font:bold 18px "Tahoma","宋体","Courier New";text-align:center;height:40px;line-height:40px;color:#000080;text-indent:0px;}
.wui-doc P,
.wui-doc P.para {font:12px "宋体","Courier New";line-height:130%;text-align:left;background-color:#F2F2F2;margin:4px 0px 4px 0px;text-indent:24px;}
.wui-doc P.note {font:normal 12px "Tahoma","宋体","Courier New";background-color:#EEEEEE;text-indent:0px;padding:2px;margin-left:24px;border:#AAAAAA 1px solid;}
.wui-doc P.box {border:#6595D6 1px solid;margin:4px 0px 4px 0px;padding:2px;text-indent:0px;text-align:left;line-height:120%;}
.wui-doc PRE     {font:12px "宋体","Courier New";line-height:130%;text-align:left;background-color:#F2F2F2;margin:4px 0px 4px 0px;}
.wui-doc P.table SPAN {width:180px;}
.wui-doc PRE.code {font:12px "宋体","Courier New";line-height:120%;text-align:left;margin:4px 0px 4px 0px;border:#DDDDDD 1px solid;background-color:#FFFFFF;}
.wui-doc BLOCKQUOTE {margin:8px 0px 8px 24px;}
.wui-doc .wui-code-html {width:100%;font:12px "Tahoma","宋体","Courier New";text-align:left;line-height:110%;border:1px solid #CCCCCC;background-color:#FFFFFF;}
.wui-doc .Box SPAN.title     {width:100px;height:16px;text-align:right;margin-bottom:2px;font:normal 12px "Tahoma","宋体","Courier New";line-height:14px;background-color:#DDDDDD;}
.wui-doc .code SPAN.code     {font:normal 12px "Tahoma","宋体","Courier New";}
.wui-doc .code SPAN.keyword  {font:normal 12px "Tahoma","宋体","Courier New";color:#0000FF;}
.wui-doc .code SPAN.function {font:normal 12px "Tahoma","宋体","Courier New";color:#800000;}
.wui-doc .code SPAN.class    {font:normal 12px "Tahoma","宋体","Courier New";color:#000080;}
.wui-doc .code SPAN.string   {line-height:14px;color:#800080;}
.wui-doc .code SPAN.note     {line-height:14px;color:#008000;}
.wui-doc .code SPAN.asptag   {line-height:14px;color:#000000;background-color:#FFFF00;}
.wui-doc .todo {color:gray;}
-->
</style>
<script type="text/javascript">
<!--
window.onload = function(){
	createContents();
};
function $(id){
	return window.document.getElementById(id);
}
function createContents(){
	var c = $("contents");
	var p = c;
	var l = 1, num = 0;

	var nodes = c.parentNode.childNodes;
	for(var i = 0, len = nodes.length; i < len; i++){
		if((/^h[1-6]$/i).test(nodes[i].tagName)){
			var title = nodes[i].innerHTML;
			if(title == "目录")
				continue;
			var n = parseInt(nodes[i].tagName.substr(1));
			if(n > l){
				var ul = window.document.createElement("ul");
				p = p.lastChild.appendChild(ul);
				ul = null;
				l++;
			}else if(n < l){
				while(n < l){
					p = p.parentNode.parentNode;
					l--;
				}
			}else{  //n == l
			}
			var li = window.document.createElement("li");
			li.innerHTML = "<a href=\"#_" + num + "\">" + title + "</a>";
			p.appendChild(li);
			li = null;
			nodes[i].innerHTML = "<a name=\"_" + num + "\"></a>" + title;
			num++;
		}
	}
	nodes = null;

	p = null;
	c = null;
}
//-->
</script>
</head>
<body>
<div class="body">
<div class="wui-doc">

<p class="title">邮箱前端系统架构</p>

<h1>目录</h1>
<ul id="contents"></ul>

<h1>1. 邮箱前端框架</h1>
<h2>1.1 AJAX框架(alzui-mini)</h2>
<h3>1.1.1 简介</h3>
<p>完全自主开发</p>
<p>存在一个完整版的框架 <b>alzui</b></p>
<p>层层扩展机制</p>
<p>(近乎)完全面向对象</p>
<p>类格式规范，库形式单一</p>
<p>全局唯一对象，对外干扰少，抗干扰能力强，可以很容易和其他代码并行</p>

<h3>1.1.2 文件组成</h3>
<div style="height:100%;overflow:auto;">
	<div style="float:left;width:60%;">
		<ul style="margin:0px;">
			<li><b>__init__mini.lib.js</b><ul>
				<li style="color:red;">Context</li>
				<li>alz.lang.AObject</li>
				<li>alz.lang.Exception</li>
				<li>alz.core.WebRuntime</li>
				<li>alz.core.ManagerBase</li>
				<li>alz.core.LibManager</li>
				<li>alz.core.ScriptLoader</li>
				<li>alz.core.LibLoader</li>
				<li>alz.core.WebRuntime_init</li>
			</ul></li>
			<li><b>core.lib.js</b><ul>
				<li>alz.core.DOMUtil</li>
				<li>alz.core.BoxElement</li>
				<li>alz.layout.AbstractLayout</li>
				<li>alz.layout.BorderLayout</li>
				<li>alz.core.AjaxEngine_mini</li>
				<li>alz.core.Ajax</li>
				<li>alz.template.TrimPath</li>
				<li>alz.template.Template</li>
				<li>alz.template.ParseError</li>
				<li>alz.template.TemplateManager</li>
				<li>alz.core.ActionCollection</li>
				<li>alz.core.EventTarget</li>
				<li>alz.core.Application_mini</li>
				<li>alz.core.AppManager_mini</li>
				<li>alz.core.Plugin</li>
				<li>alz.core.PluginManager</li>
				<li>alz.core.ProductManager</li>
				<li>alz.core.WebRuntime_core</li>
			</ul></li>
			<li><b>ui.lib.js</b><ul>
				<li>alz.mui.ToggleGroup</li>
				<li>alz.mui.ToggleManager</li>
				<li>alz.mui.Component</li>
				<li>alz.mui.TextHistory</li>
				<li>alz.mui.TextItem</li>
				<li>alz.mui.LineEdit</li>
				<li>alz.mui.Console</li>
				<li>alz.mui.Iframe</li>
				<li>alz.mui.BitButton</li>
				<li>alz.mui.ToggleButton</li>
				<li>alz.mui.ToolBar</li>
				<li>alz.mui.ModalPanel</li>
				<li>alz.mui.Container</li>
				<li>alz.mui.Panel</li>
				<li>alz.mui.Pane</li>
				<li>alz.mui.Workspace</li>
				<li>alz.mui.DropDown</li>
				<li>alz.mui.Popup</li>
				<li>alz.mui.ListItem</li>
				<li>alz.mui.Dialog</li>
				<li>alz.mui.TabPage</li>
				<li>alz.mui.WindowSkinWINXP</li>
				<li>alz.mui.WindowSkinWIN2K</li>
				<li>alz.mui.SysBtn</li>
				<li>alz.mui.Window</li>
				<li>alz.core.WebRuntime_ui</li>
			</ul></li>
		</ul>
	</div>
	<div style="float:right;width:40%;">
<b>类继承关系</b>
<pre style="margin:0px;padding:4px;line-height:100%;">
AObject
├WebAppRuntime
├LibLoader
├DOMUtil
├AjaxEngine
├EventTarget
│├Application
│└Component
│  ├BitButton
│  │└ToggleButton
│  ├ToolBar
│  ├ModalPanel
│  ├Container
│  │├Panel
│  │├Pane
│  │└Workspace
│  ├DropDown
│  ├Popup
│  ├ListItem
│  ├Dialog
│  └TabPage
├AppManager
├ToggleGroup
├ToggleManager
└ActionManager
</pre>
	</div>
</div>

<h3>1.1.3 框架的基本使用</h3>
<p style="text-indent:0px;"><span style="color:blue;">&lt;script</span>
<span style="color:red;">type</span><span style="color:blue;">=</span><span style="color:#800080;">"text/javascript"</span>
<span style="color:red;">src</span><span style="color:blue;">=</span><span style="color:#800080;">"&lt;{$_JS_VERSION_}&gt;__init__mini.lib.js"</span>
<span style="color:red;">charset</span><span style="color:blue;">=</span><span style="color:#800080;">"utf-8"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">pathcss</span><span style="color:blue;">=</span><span style="color:#800080;">"&lt;{$_CSS_PATH_}&gt;"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">pathskin</span><span style="color:blue;">=</span><span style="color:#800080;">"&lt;{$_PATH_SKIN_}&gt;"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">pathimg</span><span style="color:blue;">=</span><span style="color:#800080;">"&lt;{$_IMAGE_PATH_}&gt;"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">pathlib</span><span style="color:blue;">=</span><span style="color:#800080;">"&lt;{$_JS_VERSION_}&gt;"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">pathapp</span><span style="color:blue;">=</span><span style="color:#800080;">"&lt;{$_JS_VERSION_}&gt;"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">conf</span><span style="color:blue;">=</span><span style="color:#800080;">"{
<br />&nbsp;&nbsp;&nbsp;&nbsp;product:'data_50.js',
<br />&nbsp;&nbsp;&nbsp;&nbsp;username:'&lt;{$_USERNAME_}&gt;',
<br />&nbsp;&nbsp;&nbsp;&nbsp;uid:'&lt;{$_UID_}&gt;',
<br />&nbsp;&nbsp;&nbsp;&nbsp;skinid:&lt;{$_SKIN_ID_}&gt;,
<br />&nbsp;&nbsp;&nbsp;&nbsp;act:'&lt;{$_DEFAULT_ACTION_}&gt;',
<br />&nbsp;&nbsp;&nbsp;&nbsp;outmail:'&lt;{$_OUTMAIL_}&gt;',
<br />&nbsp;&nbsp;&nbsp;&nbsp;token:'&lt;{$_TOKEN_}&gt;',
<br />&nbsp;&nbsp;&nbsp;&nbsp;mailinfo:&lt;{$_MAILINFO_}&gt;,
<br />&nbsp;&nbsp;&nbsp;&nbsp;folders:&lt;{$_FOLDERS_}&gt;,
<br />&nbsp;&nbsp;&nbsp;&nbsp;contacts:&lt;{$_CONTACTS_}&gt;,
<br />&nbsp;&nbsp;&nbsp;&nbsp;groups:&lt;{$_GROUPS_}&gt;,
<br />&nbsp;&nbsp;&nbsp;&nbsp;settings:&lt;{$_SETTINGS_}&gt;,
<br />&nbsp;&nbsp;&nbsp;&nbsp;plugin_open:false,
<br />&nbsp;&nbsp;&nbsp;&nbsp;servertime:&lt;{$_SERVTIME_}&gt;,
<br />&nbsp;&nbsp;&nbsp;&nbsp;loginrequest:&lt;{$_LOGIN_REQUEST_}&gt;/*,
<br />&nbsp;&nbsp;&nbsp;&nbsp;systemerror:&lt;{$_SYSTEM_ERROR_}&gt;*/
<br />&nbsp;&nbsp;}"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">css</span><span style="color:blue;">=</span><span style="color:#800080;">"mailui.css,maillist.css,#{$skinid}.css"</span>
<br />&nbsp;&nbsp;<span style="color:#FF00FF;">lib</span><span style="color:blue;">=</span><span style="color:#800080;">"core,ui,mailui,#index50"</span>
<br />&nbsp;&nbsp;<span style="color:blue;">&gt;&lt;/script&gt;</span></pre>

<h3>1.1.4 类代码编写格式</h3>
<p>单根继承体系(AObject)</p>
<p>防止内存泄露的基础接口(AObject.dispose)</p>

<blockquote><pre style="border:1px solid gray;">
_class("ClassA", "", function(){
	this._init = function(){
		this.aaa = "";
	};
	this.dispose = function(){
	};
	this.xxx = function(){
	};
});
</pre></blockquote>

<h3>1.1.5 库文件格式</h3>
<p>WebAppRuntime.createContext(libName);</p>
<p>WebAppRuntime.regLib(libName, {init:function(){},dispose:function(){}});</p>
<p>WebAppRuntime.regLib(libName, function(){});</p>
<blockquote><pre style="border:1px solid gray;">
(<span style="color:blue;">function</span>(){<span style="color:blue;">with</span>(<span style="color:#000080;">runtime</span>.createContext("<u>libName</u>")){

<span style="color:#000080;">_class</span>("ClassA", "", <span style="color:blue;">function</span>(){...});
<span style="color:#000080;">_class</span>("ClassB", ClassA, <span style="color:blue;">function</span>(){...});
<span style="color:#000080;">_class</span>("AppDemo", Application, <span style="color:blue;">function</span>(){...});

<span style="color:#000080;">runtime</span>.regLib("<u>libName</u>", {
	init: <span style="color:blue;">function</span>(){  //加载之后的初始化工作
		<span style="color:#000080;">application</span> = <span style="color:#000080;">runtime</span>.createApp("AppDemo");
	},
	dispose: <span style="color:blue;">function</span>(){
	}
});

}})(<span style="color:blue;">this</span>);
</pre></blockquote>

<h3>1.1.6 异步调用引擎</h3>
<p>内置请求队列管理</p>
<p>AjaxEngine.netInvoke(method, url, postData, type[, agent, funName, cbArgs]);</p>
<p>AjaxEngine.netInvokeQueue(queue, agent, funName);</p>

<h3>1.1.7 自定义事件工作模型</h3>
<p>EventTarget.addEventListener(type, eventHandle, useCapture);</p>
<p>EventTarget.removeEventListener(type, eventHandle, useCapture);</p>
<p>EventTarget.dispatchEvent(ev);</p>

<h3>1.1.8 组件化开发</h3>
<p>Component组件</p>
<p>组件的基础性接口</p>
<p>盒子模型问题</p>
<p>布局大小自适应问题</p>
<p>Container类的布局支持，替代HTML流布局和float布局等</p>

<h2>1.2 邮箱基础代码</h2>

<h3>1.2.1 文件组成</h3>
<ul>
	<li><b>mailui.lib.js</b><ul>
		<li>Email</li>
		<li>EmailList</li>
		<li>UploadX</li>
		<li>SinaTemplate</li>
		<li>AutoComplete</li>
		<li style="color:#000080;">TemplateManager</li>
		<li style="color:#000080;">TrimPath</li>
		<li style="color:#000080;">Template</li>
		<li style="color:#000080;">ParseError</li>
		<li>BitButton</li>
		<li>ComboBox</li>
		<li style="color:#000080;">ActionElement</li>
		<li style="color:#000080;">LinkLabel</li>
		<li style="color:#000080;">Button</li>
		<li style="color:#000080;">CheckBox</li>
		<li style="color:#000080;">ComboBox</li>
		<li style="color:#000080;">FormElement</li>
		<li>TabChannel</li>
		<li>MailDialog</li>
		<li style="color:#000080;">SelectionManager</li>
		<li style="color:#000080;">ListItem</li>
		<li style="color:#000080;">ListBox</li>
		<li style="color:#000080;">Pane</li>
		<li>DataModel</li>
		<li>AppMail</li>
	</ul></li>
	<li><b>index5.lib.js</b><ul>
		<li>YellowOff</li>
		<li>HistoryManager</li>
		<li>PaneFrame</li>
		<li>AppMailIndex5</li>
	</ul></li>
	<li><b>mailbox.lib.js</b><ul>
		<li>Weather</li>
		<li>AppMailBox</li>
	</ul></li>
	<li><b>maillist.lib.js</b><ul>
		<li>PageOperation</li>
		<li>AppMailList</li>
	</ul></li>
	<li><b>reader.lib.js</b><ul>
		<li>AppMailReader</li>
	</ul></li>
	<li><b>writer.lib.js</b><ul>
		<li>ContactItem</li>
		<li>ContactList</li>
		<li>GroupItem</li>
		<li>GroupList</li>
		<li>PaperModel</li>
		<li>PaperList</li>
		<li>TipBox</li>
		<li>AppMailWriter</li>
	</ul></li>
	<li><b>addresslist.lib.js</b><ul>
		<li>GroupItem</li>
		<li>GroupList</li>
		<li>ContactRow</li>
		<li>ContactTable</li>
		<li>PaneMain</li>
		<li>PaneContactTable</li>
		<li>FormAgent</li>
		<li>AppAddress</li>
	</ul></li>
	<li class="todo"><b>setting.lib.js</b>(重构中)<ul>
		<li>AppMailSetting</li>
	</ul></li>
	<li><b>reg.lib.js</b><ul>
		<li>AppMailReg</li>
	</ul></li>
	<li><b>space.lib.js</b><ul>
		<li>AppMailSpace</li>
	</ul></li>
</ul>

<h1>2. 换肤机制</h1>

<h2>相关的接口</h2>
<p>AppMailIndex5.onSettingChange</p>

<h1>3. 前端模板引擎</h1>

<h2>自定义模板引擎</h2>
<p>整合trimpath</p>
<p>支持html,tpl,asp,tmpl四种基本类型</p>

<h2>模板的工作原理</h2>
<p>load tpl -> parse -> render(get tpl -> invoke)</p>
<p class="todo">[此处配图]</p>

<h1>4. action工作原理</h1>

<p>action机制的设计目的，HTML中不写一行JS代码，实现HTML代码和JS代码的完全分离</p>

<h2>支持的 Action 动作组件有</h2>

<ul style="text-indent:12px;">
	<li>表单  ： FORM</li>
	<li>超链接： A</li>
	<li>按钮  ： INPUT(type=button)</li>
	<li>复选框： INPUT(type=checkbox)</li>
	<li>复选框： INPUT(type=submit)</li>
	<li>复选框： INPUT(type=reset)</li>
	<li>列表框： SELECT</li>
</ul>

<h2>相关的接口</h2>
<p>Pane.initComponents(element);</p>
<p>AppMail.initComponents(element[, owner]);</p>
<p>AppMail.initActionElements(idList);</p>
<p>AppMail.doAction(action, sender);</p>

<h2>需要改进的工作逻辑</h2>
<p>原始的 obj.innerHTML = "xxxx"; 被替换为</p>
<p>Template.render(element, tplName[, param1, param2]);</p>

<h2>扩展应用</h2>
<p>可以把一些特定的效果按照类似Action的机制封装为一些可复用的组件</p>

<h1>5. 页面结构</h1>
<p>单页面应用</p>
<ul>
	<li>AppMail</li><ul>
		<li>AppMailIndex5</li>
		<li>AppMailBox</li>
		<li>AppMailList</li>
		<li>AppMailReader</li>
		<li>AppMailWriter</li>
		<li>AppAddress</li>
		<li>AppMailSetting</li>
		<li>AppMailReg</li>
		<li>AppMailSpace</li>
	</ul>
</ul>

<h1>6. 前后端数据通讯协议</h1>
<p>JSON格式</p>

<h2>后端返回数据的统一格式</h2>
<pre>{
	result: true,  //返回结果true|false
	errno: 0,      //错误编号
	msg: "",    //错误提示信息
	info:"",    //本次请求的信息，标志这是哪个请求
	data: null     //返回的真实数据：null | {...}
	//----
	servertime:12312344,
	act:'xxxx'
}</pre>

<h3>1.邮箱核心</h3>

<h4>1.邮件夹</h4>
<h4>2.邮件</h4>

<h3>2.通讯录</h3>

<h4>1.联系人</h4>
<h4>2.联系人小组</h4>
<h4>3.联系人导入/导出</h4>
<h4>4.通讯录设置</h4>
<h4>5.搜索联系人</h4>
<h4>6.打印</h4>

<h3>3.邮箱设置</h3>

</div>
</div>
</body>
</html>